import * as THREE from 'three'
import { OrbitControls } from 'three/addons'
import { GLTFLoader } from 'three/addons'
import Stats from 'three/examples/jsm/libs/stats.module.js'

class Scene {
  container: Element | null
  /**场景 */
  scene!: THREE.Scene
  /**相机 */
  camera!: THREE.PerspectiveCamera
  /**渲染器 */
  renderer!: THREE.WebGLRenderer
  /**轨道控制器 */
  controls!: OrbitControls
  objects: THREE.Mesh[] = []
  stats: any
  update!: Function

  constructor(selector: string, update?: Function) {
    if (update) {
      this.update = update
    }
    this.container = document.querySelector(selector) //获取容器
    this.init() //初始化
    this.animate()//循环函数
  }

  init() {
    // 初始化场景
    this.initScene()
    // 初始化辅助轴
    this.initAxesHelper()
    // 初始化灯光
    this.initLight()
    // 初始化平面
    this.initGeometry()
    // 初始化相机
    this.initCamera()
    // 初始化渲染器
    this.initRender()
    // 初始化轨道控制器
    this.initControls()
    // 监听场景大小改变，重新渲染尺寸
    window.addEventListener('resize', this.onWindowResize.bind(this))
    this.initStats()
  }

  /** 设置场景 */
  initScene() {
    this.scene = new THREE.Scene()
    this.scene.background = new THREE.Color(0xa0a0a0)
  }

  /** 设置辅助线 */
  initAxesHelper() {
    const axesHelper = new THREE.AxesHelper(10)
    this.scene.add(axesHelper)
  }

  /** 设置场景灯光 */
  initLight() {
    const hesLight = new THREE.HemisphereLight(0xffffff, 0x444444)
    hesLight.intensity = 0.6
    this.scene.add(hesLight)

    const dirLight = new THREE.DirectionalLight()
    dirLight.position.set(100, 100, 100)
    this.scene.add(dirLight)
  }

  /**平面 */
  initGeometry() {
    const planeGeometry = new THREE.PlaneGeometry(500, 500)
    const planeMaterial = new THREE.MeshLambertMaterial({
      color: 0x000611,
      side: THREE.DoubleSide,
    })
    const plane = new THREE.Mesh(planeGeometry, planeMaterial)
    plane.rotateX(Math.PI / 2)
    this.scene.add(plane)
  }

  /** 设置相机 */
  initCamera() {
    this.camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000)
    this.camera.position.set(50, 30, 50)
  }

  /** 设置渲染器 */
  initRender() {
    this.renderer = new THREE.WebGLRenderer({
      //设置抗锯齿
      antialias: true,
      // 设置对数深度缓冲区，优化深度冲突问题
      // logarithmicDepthBuffer: true,
    })
    // this.renderer.autoClearDepth = true
    //设置屏幕像素比
    this.renderer.setPixelRatio(window.devicePixelRatio)
    //渲染的尺寸大小
    this.renderer.setSize(window.innerWidth, window.innerHeight)
    //解决加载gltf格式模型纹理贴图和原图不一样问题
    // this.renderer.outputEncoding = THREE.sRGBEncoding
    // 添加到容器
    this.container?.appendChild(this.renderer.domElement)
  }

  initControls() {
    this.controls = new OrbitControls(this.camera, this.renderer.domElement)
    this.controls.maxDistance = 100
    this.controls.maxPolarAngle = Math.PI / 2.1
    this.controls.minZoom = 10 // 禁止缩放
  }

  render() {
    this.renderer.render(this.scene, this.camera)
  }

  animate() {
    this.update && this.update()
    this.controls.update()
    if (this.stats) {
      this.stats.update()
    }
    this.renderer.render(this.scene, this.camera)
    requestAnimationFrame(this.animate.bind(this))
  }

  onWindowResize() {
    this.camera.aspect = window.innerWidth / window.innerHeight
    this.camera.updateProjectionMatrix()//更新矩阵，将3d内容投射到2d画面上转换
    this.renderer.setSize(window.innerWidth, window.innerHeight)
  }

  // addGLTFModel(modelName: any) {
  //   return new Promise((resolve, reject) => {
  //     const loader = new GLTFLoader().setPath('3dModels/')
  //     loader.load(modelName, (gltf) => {
  //       let scale = 0.07
  //       gltf.scene.scale.set(scale, scale, scale)
  //       this.scene.add(gltf.scene)
  //       resolve(gltf)
  //     })
  //   })
  // }

  /**性能监视器 */
  initStats() {
    this.stats = new Stats()
    this.stats.setMode(0)
    this.stats.domElement.style.position = 'absolute'
    this.stats.domElement.style.left = '0px'
    this.stats.domElement.style.top = '0px'
    document.body.appendChild(this.stats.domElement)
  }
}


export default Scene